/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hoja.de.trabajo5;

/**
 *
 * @author FAMILIA
 */



import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;


public class BancoCircular {
    public static void main(String[] args) {
    
        int hora = 0; //Hora en que llega.
        int colaP = 0; //Número de cola (1,2,3,4)
        Evento temp; //Evento temporal para poder ejecutar el evento necesario.
        int tiempoTotal = 0; //Tiempo total que se tardarán todos los clientes.
        
        
        int numClientes = 0; //Número total de clientes atendidos.
        Random trans = new Random(); //Para poder asignar un tiempo de transacción.
        
        
        ColaCircular<Cliente> cola1 = new ColaCircular<Cliente>();
        ColaCircular<Cliente> cola2 = new ColaCircular<Cliente>();
        ColaCircular<Cliente> cola3 = new ColaCircular<Cliente>();
        ColaCircular<Cliente> cola4 = new ColaCircular<Cliente>();
        
        LinkedList<Evento> listaEvento = new LinkedList<Evento>();
        
        System.out.println("+                               +");
        System.out.println("|         Banco de UVG          |");
        System.out.println("+           BIENBENIDO!!!!      +");
        System.out.println();
        
        //Se ingresan todos clientes que entrarán al banco.
        do{
            System.out.println("De el tiempo de ingreso de cada cliente, -1 cuando termine de ingresar ");
            hora = obtenerTiempo();
            if(listaEvento.size() !=0 ){
                
                
                
                if(hora > listaEvento.getLast().getHora() && hora <= 480){
                    //tiempoTrans = trans.nextInt(30)+1;
                    listaEvento.add(new Evento(hora, false, 0));
                    
                }
                else{
                    System.out.println("Ingrese un tiempo mayor al anterior");
                }
            }
            else{
                if(hora<=480){
                    listaEvento.add(new Evento(hora, false, 0));
                }
                else{
                    
                }
            }
            
        }while(hora != -1);
        
        //Se ejecuta la lista de eventos.
        do{
            temp = listaEvento.removeFirst();
            //Verificar que el evento no sea de salida.
            if(!temp.getSalida()){
                //Se asigna una cola del banco, la más corta.
                colaP = colaP(cola1, cola2, cola3, cola4);
                if(colaP == 1){
                    try {
                        int tiempo = trans.nextInt(30)+1;
                        cola1.add(new Cliente(temp.getHora(), tiempo));
                        tiempoTotal = tiempoTotal + tiempo; //Se agrega el tiempo de transacción al tiempo total.
                        numClientes ++; //Se atendió a un cliente.
                        //Se agrega un evento de salida a la lista de eventos.
                        for(int cont=0; cont < listaEvento.size(); cont++){
                            //Se recorre la lista de eventos, para buscar dónde se debe poner el evento para remover el cliente que acaba de ingresar.
                            Cliente actual = cola1.peek();
                            
                            
                            
                            if(actual.getTiempoSalida() >= listaEvento.get(cont).getHora()){
                                //Se agrega el evento de salida
                                listaEvento.add(cont--, new Evento(actual.getTiempoSalida(), true, 1));
                            }
                            break;
                        }
                    } 
                    catch (Exception ex) {
                    }
                }
                if(colaP == 2){
                    try {
                        int tiempo = trans.nextInt(30)+1;
                        cola2.add(new Cliente(temp.getHora(), tiempo));
                        tiempoTotal = tiempoTotal + tiempo; //Se agrega el tiempo de transacción al tiempo total.
                        numClientes ++; //Se atendió a un cliente.
                        
                        
                        
                        //Se agrega un evento de salida a la lista de eventos.
                        for(int cont=0; cont < listaEvento.size(); cont++){
                            //Se recorre la lista de eventos, para buscar dónde se debe poner el evento para remover el cliente que acaba de ingresar.
                            //System.out.println("Llegué");
                            Cliente actual = cola2.peek();
                            if(actual.getTiempoSalida() >= listaEvento.get(cont).getHora()){
                                listaEvento.add(cont--, new Evento(actual.getTiempoSalida(), true, 1));
                            }
                            break;
                        }
                    } 
                    catch (Exception ex) {
                    }
                }
                if(colaP == 3){
                   try {
                        int tiempo = trans.nextInt(30)+1;
                        cola3.add(new Cliente(temp.getHora(), tiempo));
                        tiempoTotal = tiempoTotal + tiempo; //Se agrega el tiempo de transacción al tiempo total.
                        numClientes ++; //Se atendió a un cliente
                        
                        
                        //Se agrega un evento de salida a la lista de eventos.
                        
                        
                        
                        
                        for(int cont=0; cont < listaEvento.size(); cont++){
                            //Se recorre la lista de eventos, para buscar dónde se debe poner el evento para remover el cliente que acaba de ingresar.
                            Cliente actual = cola3.peek();
                            if(actual.getTiempoSalida() >= listaEvento.get(cont).getHora()){
                                //Se agrega el evento de salida
                                listaEvento.add(cont--, new Evento(actual.getTiempoSalida(), true, 1));
                            }
                            break;
                        }
                    } 
                    catch (Exception ex) {
                    }
                }
                if(colaP == 4){
                    try {
                        int tiempo = trans.nextInt(30)+1;
                        cola4.add(new Cliente(temp.getHora(), tiempo));
                        tiempoTotal = tiempoTotal + tiempo; //Se agrega el tiempo de transacción al tiempo total.
                        numClientes ++; //Se atendió a un cliente.
                        //Se agrega un evento de salida a la lista de eventos.
                        for(int cont=0; cont < listaEvento.size(); cont++){
                            
                            
                            //Se recorre la lista de eventos, para buscar dónde se debe poner el evento para remover el cliente que acaba de ingresar.
                            Cliente actual = cola4.peek();
                            
                            
                            
                            if(actual.getTiempoSalida() >= listaEvento.get(cont).getHora()){
                                //Se agrega el evento de salida
                                listaEvento.add(cont--, new Evento(actual.getTiempoSalida(), true, 1));
                            }
                            break;
                        }
                    } 
                    catch (Exception ex) {
                    }
                }
                
                
            }
            //Si es un evento de salida, se elimina el evento.
            else{
                
                //Se elimina un cliente la cola1.
                if(listaEvento.peek().getcola() == 1){
                    cola1.remove();
                }
                //Se elimina un cliente de la cola2.
                if(listaEvento.peek().getcola() == 2){
                    cola2.remove();
                }
                //Se elimina un cliente de la cola3.
                if(listaEvento.peek().getcola() == 3){
                    cola3.remove();
                }
                //Se elimina un cliente de la cola4.
                if(listaEvento.peek().getcola() == 4){
                    cola4.remove();
                }
                //Se elimina el evento de la lista de eventos.
                listaEvento.remove();    
            }
            
        }while(!listaEvento.isEmpty());
        System.out.println("Tiempo por cliente: " +tiempoTotal/numClientes + " minutos."); 
    }
    

    /**
     * Método para poder identificar, qué cola es la más corta.
     * @param c1 Cola 1 de la ventanilla 1.
     * @param c2 Cola 2 de la ventanilla 2.
     * @param c3 Cola 3 de la ventanilla 3.
     * @param c4 Cola 4 de la ventanilla 4.
     * @return Un número entero que representa el número de cola, en el que hay menos clientes.
     */
    
    
    
    public static int colaP(ColaCircular<Cliente> c1, ColaCircular<Cliente> c2, ColaCircular<Cliente> c3, ColaCircular<Cliente> c4){
        //Variables locales.
        int cola = 0;
        int cola1 = c1.size();
        int cola2 = c2.size();
        int cola3 = c3.size();
        int cola4 = c4.size();
        
        //Cola 1 es la más corta.
        if(cola1 <= cola2){
            if(cola1 <= cola3){
                if(cola1 <= cola4){
                    cola = 1;
                }
            }
        }
        //Cola 2 es la más corta.
        if(cola2 <= cola1){
            if(cola2 <= cola3){
                if(cola2 <= cola4){
                    cola = 2;
                }
            }
        }
        //Cola 3 es la más corta.
        if(cola3 <= cola2){
            if(cola3 <= cola1){
                if(cola3 <= cola4){
                    cola = 3;
                }
            }
        }
        //Cola 4 es la más corta.
        if(cola4 <= cola2){
            if(cola4 <= cola3){
                if(cola4 <= cola1){
                    cola = 4;
                }
            }
        }
        //Se regresa el número de cola más corta.
        return cola;
    }
    
    /**
     * Metodo para poder ingresar correctamente numeros.
     * no recibe ningún parámetro.
     * @return El tiempo que el usuario ingreso, sí es correcto.
     */
    public static int obtenerTiempo(){
        Scanner input = new Scanner(System.in);
        int num=0;
        try{
            num = input.nextInt();
        }
        catch(InputMismatchException e){
            System.out.println("ERROR... opcion inexistente");
        }
        finally{
            input.nextLine();//se atrapa el enter
        }
        return num;
    }
}
        

